#ifndef SDCard_Updater_h
#define SDCard_Updater_h

// Local include.
#include "Configuration.h"

// Local include.
#include <IUpdater.h>

constexpr char OPEN_FILE_FAILED[] = "Failed to open file (%s), ensure path is correct and SD card exist and is initalized";


/// @brief IUpdater implementation that uses the c fopen function (https://cplusplus.com/reference/cstdio/fopen/),
/// under the hood to write the given binary firmware data into a file. Can be used to write the binary into an intermediate SD card instead of directly updating to flash memory
/// @tparam Logger Implementation that should be used to print error messages generated by internal processes and additional debugging messages if THINGSBOARD_ENABLE_DEBUG is set, default = DefaultLogger
template <typename Logger = DefaultLogger>
class SDCard_Updater : public IUpdater {
  public:
    SDCard_Updater(char const * file_path)
      : m_path(file_path)
    {
        // Nothing to do
    }

    bool begin(size_t const & firmware_size) override {
        FILE* file = fopen(m_path, "w");
        if (file == nullptr) {
            Logger::printfln(OPEN_FILE_FAILED, m_path);
            return false;
        }
        fclose(file);
        return true;
    }
  
    size_t write(uint8_t * payload, size_t const & total_bytes) override {
        FILE* file = fopen(m_path, "a");
        if (file == nullptr) {
            Logger::printfln(OPEN_FILE_FAILED, m_path);
            return 0;
        }
        size_t const bytes_written = fwrite(payload, 1, total_bytes, file);
        fclose(file);
        return bytes_written;
    }

    void reset() override {
        end();
    }
  
    bool end() override {
        return remove(m_path) == 0;
    }

  private:
    char const * m_path = {}; // Path to the file the binary data is written into
};

#endif // SDCard_Updater_h
